//
// Created by dg on 2023/12/29.
//

#include "EglHelper.h"
#include "./Log.h"

#define LOG_TAG "EglHelper"

EglHelper::EglHelper() {
    mEglDisplay = EGL_NO_DISPLAY;
    mEglSurface = EGL_NO_SURFACE;
    mEglConfig = NULL;
    mEglContext = EGL_NO_CONTEXT;
}

EglHelper::~EglHelper() {
    destroyEgl();
}

int EglHelper::initEgl(EGLNativeWindowType win) {

    //1.获取设备
    mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    if (mEglDisplay == EGL_NO_DISPLAY) {
        EGLint res = eglGetError();
        LOGE("eglGetDisplay error:%d", res);
        return -1;
    }

    // 2.EGL初始化
    EGLint *version = new EGLint[2];
    if (!eglInitialize(mEglDisplay, &version[0], &version[1])) {
        LOGE("eglInitialize error:%d", eglGetError());
        delete[] version;
        version = nullptr;
        return -1;
    }
    delete[] version;
    version = nullptr;

    //上面两步就可以把输出和设备的屏幕桥接起来了
    // 但是需要指定一些配置项:
    // 色彩格式 像素格式 RGBA的表示 以及 SurfaceType
    // 3.资源配置，例如颜色位数等
    const EGLint attribs[] = {
            EGL_RED_SIZE, 8,
            EGL_GREEN_SIZE, 8,
            EGL_BLUE_SIZE, 8,
            EGL_ALPHA_SIZE, 8,
            EGL_DEPTH_SIZE, 8,
            EGL_STENCIL_SIZE, 8,
            EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
            EGL_NONE
    };

    EGLint num_config;
    //3.1 根据所需的参数获取符合该参数的config_size，主要是解决有些手机eglChooseConfig失败的兼容性问题
    if(!eglChooseConfig(mEglDisplay, attribs, NULL, 1, &num_config)) {
        LOGE("eglChooseConfig error 1");
        return -1;
    }

    //4.根据获取到的config_size得到eglConfig
    if (!eglChooseConfig(mEglDisplay, attribs, &mEglConfig, num_config, &num_config)) {
        LOGE("eglChooseConfig 2");
        return -1;
    }

    // 5.创建上下文
    int attrib_list[] = {
            EGL_CONTEXT_CLIENT_VERSION, 2,
            EGL_NONE
    };
    mEglContext = eglCreateContext(mEglDisplay, mEglConfig, EGL_NO_CONTEXT, attrib_list);
    if (mEglContext == EGL_NO_CONTEXT) {
        LOGE("eglCreateContext ERROR");
        return -1;
    }

    // Surface实际上是一个FrameBuffer
    //6. 创建渲染的Surface
    mEglSurface = eglCreateWindowSurface(mEglDisplay, mEglConfig, win, NULL);
    if (mEglSurface == EGL_NO_SURFACE) {
        LOGE("eglCreateWindowSurface error");
        return -1;
    }

//    //7.使用
    if (!eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
        LOGE("eglMakeCurrent error");
        return -1;
    }
    LOGD("egl init success");
    return 0;
}

int EglHelper::swapBuffers() {

    if (mEglDisplay != EGL_NO_DISPLAY && mEglSurface != EGL_NO_SURFACE) {
        if (eglSwapBuffers(mEglDisplay, mEglSurface)) {
            return 0;
        }
    }
    LOGE("eglSwapBuffers error");
    return -1;
}

void EglHelper::destroyEgl() {

    if (mEglDisplay != EGL_NO_DISPLAY) {
        // 解绑display上的eglContext 和 surface
        eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
    }
    // 销毁surface 和 context
    if (mEglDisplay != EGL_NO_DISPLAY && mEglSurface != EGL_NO_SURFACE) {
        eglDestroySurface(mEglDisplay, mEglSurface);
        mEglSurface = EGL_NO_SURFACE;
    }

    if (mEglDisplay != EGL_NO_DISPLAY && mEglContext != EGL_NO_CONTEXT) {
        eglDestroyContext(mEglDisplay, mEglContext);
        mEglContext = EGL_NO_CONTEXT;
    }

    if (mEglDisplay != EGL_NO_DISPLAY) {
        eglTerminate(mEglDisplay);
        mEglDisplay = EGL_NO_DISPLAY;
    }
}
